import axios from "axios";
import store from "@/store";
import router from "@/router";
import { Message } from "element-ui";
import qs from "qs";

/**
 * 登录重定向
 */
function redirectLogin() {
  router.push({
    name: "login",
    query: { redirect: router.currentRoute.fullPath },
  });
}

/**
 * 刷新token
 * @returns promise
 */
async function refreshToken() {
  return axios.create()({
    method: "POST",
    url: "/front/user/refresh_token",
    data: qs.stringify({
      refreshtoken: store.state.user.refresh_token,
    }),
  });
}

const request = axios.create({});

/** 请求拦截器 */
request.interceptors.request.use(
  function (config) {
    const { user } = store.state;
    if (user && user.access_token) {
      config.headers = {
        ...config.headers,
        Authorization: user.access_token, // 设置权限
      };
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

let isRfreshing = false;
const requests: Array<any> = []; // 存储刷新状态下的401请求
/** 响应拦截器 */
request.interceptors.response.use(
  function (response) {
    // 状态为2**进入这里
    // console.log("response:", response);
    return response;
  },
  async function (error) {
    // 状态非2**进入这里
    const { response, request, message, config } = error;
    if (response) {
      // 请求发出收到响应但是状态码非2**
      const { state } = response;
      if (state === 400) {
        Message.error("请求参数错误");
      } else if (state === 401) {
        // token异常
        if (!store.state.user) {
          // 跳转重新登录
          redirectLogin();
          return Promise.reject(error);
        }
        if (!isRfreshing) {
          isRfreshing = true;
          return refreshToken()
            .then(({ data: { success, content } }) => {
              if (!success) throw new Error("刷新token 失败");
              store.commit("setUser", content);
              // 把函数队列逐一删除并执行
              const cb = requests.shift();
              cb && cb();
              // 把本次失败的请求重新发送
              return request(config);
            })
            .catch((err) => {
              // 清空token
              store.commit("setUser", null);
              redirectLogin();
              return Promise.reject(err);
            })
            .finally(() => {
              isRfreshing = false;
            });
        }
        // 刷新状态下，把请求存储在requests数组中
        return new Promise((resolve) => {
          requests.push(() => {
            resolve(request(config));
          });
        });
      } else if (state === 403) {
        Message.error("没有权限，请联系管理员");
      } else if (state === 404) {
        Message.error("请求资源不存在");
      } else {
        Message.error("服务端错误，请联系管理员");
      }
    } else if (request) {
      // 请求发出没有收到响应
      Message.error("请求超时,请重试！");
    } else {
      Message.error(`请求失败：${message}`);
    }
    // 把请求失败的错误对象继续抛出，传递给下一个
    return Promise.reject(error);
  }
);

export default request;
